package com.hkts.naturalgas.workovertime.service.serviceimpl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Joiner;
import com.hkts.naturalgas.constant.HkOverTimeConstant;
import com.hkts.naturalgas.constant.PerformanceConstant;
import com.hkts.naturalgas.feign.FeignInterface;
import com.hkts.naturalgas.flow.entity.FlowHistory;
import com.hkts.naturalgas.flow.entity.FlowInstanceinfo;
import com.hkts.naturalgas.flow.entity.FlowTaskInstance;
import com.hkts.naturalgas.flow.entity.FlowTemplateinfo;
import com.hkts.naturalgas.flow.mapper.FlowHistoryMapper;
import com.hkts.naturalgas.flow.mapper.FlowInstanceinfoMapper;
import com.hkts.naturalgas.flow.mapper.FlowTaskHandlerMapper;
import com.hkts.naturalgas.flow.mapper.FlowTaskInstanceMapper;
import com.hkts.naturalgas.flow.service.IFlowInstanceinfoService;
import com.hkts.naturalgas.flow.service.IFlowTaskHandlerService;
import com.hkts.naturalgas.flow.service.IFlowTaskInstanceService;
import com.hkts.naturalgas.organizational.entity.HontDepartment;
import com.hkts.naturalgas.organizational.entity.HontUser;
import com.hkts.naturalgas.organizational.mapper.HontDepartmentMapper;
import com.hkts.naturalgas.organizational.mapper.HontUserMapper;
import com.hkts.naturalgas.performance.performanceTo.HontUserTo;
import com.hkts.naturalgas.performance.performanceTo.SubmitPerformanceDTo;
import com.hkts.naturalgas.performance.performanceVo.HkAssessmentRecordVo;
import com.hkts.naturalgas.performance.service.IHkAssessmentInfoService;
import com.hkts.naturalgas.utils.*;
import com.hkts.naturalgas.workovertime.VO.*;
import com.hkts.naturalgas.workovertime.entity.HkOvertimeCollect;
import com.hkts.naturalgas.workovertime.entity.HkOvertimeDetail;
import com.hkts.naturalgas.workovertime.entity.HkOvertimeInfo;
import com.hkts.naturalgas.workovertime.entity.HkOvertimeUser;
import com.hkts.naturalgas.workovertime.mapper.HkOvertimeCollectMapper;
import com.hkts.naturalgas.workovertime.mapper.HkOvertimeDetailMapper;
import com.hkts.naturalgas.workovertime.mapper.HkOvertimeInfoMapper;
import com.hkts.naturalgas.workovertime.mapper.HkOvertimeUserMapper;
import com.hkts.naturalgas.workovertime.service.IHkOvertimeDetailService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hkts.naturalgas.workovertime.service.IHkOvertimeInfoService;
import com.hkts.naturalgas.workovertime.service.IHkOvertimeUserService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.apache.commons.lang.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.hkts.naturalgas.utils.DateUtils.getTransitionSix;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hml
 * @since 2023-08-31
 */
@Service
@Transactional
@Slf4j
public class HkOvertimeDetailServiceImpl extends ServiceImpl<HkOvertimeDetailMapper, HkOvertimeDetail> implements IHkOvertimeDetailService {


    @Autowired
    private HkOvertimeDetailMapper hkOvertimeDetailMapper;
    @Autowired
    private FeignInterface feignInterface;
    @Autowired
    public RedisTemplate redisTemplate;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private HkOvertimeInfoMapper hkOvertimeInfoMapper;
    @Autowired
    private HontUserMapper hontUserMapper;
    @Autowired
    private HontDepartmentMapper hontDepartmentMapper;
    @Autowired
    public IFlowInstanceinfoService flowInstanceinfoService;
    @Autowired
    public IFlowTaskInstanceService iFlowTaskInstanceService;
    @Autowired
    private FlowInstanceinfoMapper flowInstanceinfoMapper;
    @Autowired
    private HkOvertimeUserMapper hkOvertimeUserMapper;
    @Autowired
    public IHkAssessmentInfoService iHkAssessmentInfoService;
    @Autowired
    private IHkOvertimeInfoService iHkOvertimeInfoService;
    @Autowired
    private IHkOvertimeUserService iHkOvertimeUserService;
    @Autowired
    private FlowHistoryMapper flowHistoryMapper;
    @Autowired
    private FlowTaskHandlerMapper flowTaskHandlerMapper;
    @Autowired
    private HkOvertimeCollectMapper hkOvertimeCollectMapper;



    @Override
    public IPage<HkOvertimeDetail> selectPage(Page<HkOvertimeDetail> page, HkOvertimeDetail hkOvertimeDetail) {
        QueryWrapper<HkOvertimeDetail> query = Wrappers.query();
        QueryWrapper<HkOvertimeDetail> entityWrapper = getEntityWrapper(query, hkOvertimeDetail);
        return hkOvertimeDetailMapper.selectPage(page, entityWrapper);
    }


    @Override
    public List<HkOvertimeDetail> selectList(HkOvertimeDetail hkOvertimeDetail) {
        QueryWrapper<HkOvertimeDetail> query = Wrappers.query();
        QueryWrapper<HkOvertimeDetail> entityWrapper = getEntityWrapper(query, hkOvertimeDetail);
        return hkOvertimeDetailMapper.selectList(entityWrapper);
    }

    /**
     * 公共查询条件
     *
     * @param entityWrapper
     * @return
     */
    public QueryWrapper<HkOvertimeDetail> getEntityWrapper(QueryWrapper<HkOvertimeDetail> entityWrapper, HkOvertimeDetail hkOvertimeDetail) {
        //条件拼接
        if (StringUtils.isNotBlank(hkOvertimeDetail.getCreateBy())) {
            entityWrapper.like(HkOvertimeDetail.CREATE_BY, hkOvertimeDetail.getCreateBy());
        }
        if (StringUtils.isNotBlank(hkOvertimeDetail.getUpdateBy())) {
            entityWrapper.like(HkOvertimeDetail.UPDATE_BY, hkOvertimeDetail.getUpdateBy());
        }
        if (StringUtils.isNotBlank(hkOvertimeDetail.getAssessmentStatus())) {
            entityWrapper.like(HkOvertimeDetail.ASSESSMENT_STATUS, hkOvertimeDetail.getAssessmentStatus());
        }
        if (StringUtils.isNotBlank(hkOvertimeDetail.getCause())) {
            entityWrapper.like(HkOvertimeDetail.CAUSE, hkOvertimeDetail.getCause());
        }
        if (StringUtils.isNotBlank(hkOvertimeDetail.getApprovalUserId())) {
            entityWrapper.like(HkOvertimeDetail.APPROVAL_USER_ID, hkOvertimeDetail.getApprovalUserId());
        }
        if (StringUtils.isNotBlank(hkOvertimeDetail.getApprovalName())) {
            entityWrapper.like(HkOvertimeDetail.APPROVAL_NAME, hkOvertimeDetail.getApprovalName());
        }
        if (StringUtils.isNotBlank(hkOvertimeDetail.getProcessInstanceId())) {
            entityWrapper.like(HkOvertimeDetail.PROCESS_INSTANCE_ID, hkOvertimeDetail.getProcessInstanceId());
        }
        if (StringUtils.isNotBlank(hkOvertimeDetail.getIndexComment())) {
            entityWrapper.like(HkOvertimeDetail.INDEX_COMMENT, hkOvertimeDetail.getIndexComment());
        }
        return entityWrapper;
    }
    @Transactional(rollbackFor = Exception.class)
    public List<String> saveOverTimeDetail(HkOvertimeDetailVo hkOvertimeDetailVo) throws Exception {
        HontUserTo hontUserTo = feignInterface.remoteUserInfo();
        /*List<HkOvertimeUser> hkOvertimeUsers = hkOvertimeDetailVo.getHkOvertimeUsers();
        String hontUserId = hkOvertimeUsers.get(0).getHontUserId();
        HontUser hontUser = hontUserMapper.selectById(hontUserId);*/
        DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        LocalDateTime overStartTime = LocalDateTime.parse(hkOvertimeDetailVo.getStartTime(), formatter);
        LocalDateTime overEndTime = LocalDateTime.parse(hkOvertimeDetailVo.getEndTime(), formatter);
        FlowInstanceinfo flowInstanceinfo = new FlowInstanceinfo();
        flowInstanceinfo.setTemplateId(hkOvertimeDetailVo.getFlowTemplateId());
        flowInstanceinfo.setHontUserId(hontUserTo.getId());
        flowInstanceinfo.setHontUserName(hontUserTo.getNickName());
        flowInstanceinfo.setHontDepartmentId(hontUserTo.getDepartmentId());
        flowInstanceinfo.setTemplateVersion(hkOvertimeDetailVo.getTemplateVersion());

        //如果list>0 只提示

        Result<Object> objectResult = flowInstanceinfoService.initiateProcessByOverTime(flowInstanceinfo,"审核通过");
        log.info("获取流程数据：{}", objectResult);
        String instanceinfo = "";
        Map data = new HashMap();
        if (objectResult.getCode() == 500) {
            throw new Exception(objectResult.getMessage());
        }
        data = BeanConvertUtils.objectToMap(objectResult.getResult());
        if (data.get("instanceinfo") != null) {
            instanceinfo = data.get("instanceinfo").toString();
            hkOvertimeDetailVo.setProcessInstanceId(instanceinfo);
        } else {
            throw new Exception("暂无流程节点信息");
        }
        /*
         * 分部式锁
         * */
        RLock lock = redissonClient.getLock(hkOvertimeDetailVo.getSubmissionKey());
        lock.lock();
        try {

            Object o = redisTemplate.opsForValue().get(HkOverTimeConstant.SUBMISSION_KEY + hkOvertimeDetailVo.getSubmissionKey());
            if (o == null) {
                throw new Exception("请勿重复提交！");
            }

            LocalDateTime now = LocalDateTime.now();
            HkOvertimeInfo hkOvertimeInfo = new HkOvertimeInfo();
            HkOvertimeDetail hkOvertimeDetail = BeanConvertUtils.copy(hkOvertimeDetailVo,
                    HkOvertimeDetail.class);
            //hkOvertimeInfo.setAssessmentName();
            boolean finish = false;
            //当前登录人等级
            if (data.get("finish") != null) {
                finish = Boolean.parseBoolean(data.get("finish").toString());
                if (finish) {
                    hkOvertimeInfo.setAssessmentStatus("1");
                    hkOvertimeInfo.setEndTime(LocalDateTime.now());
                } else {
                    hkOvertimeInfo.setAssessmentStatus("0");
                }
            } else {
                throw new Exception("未查询到该节点人员信息！");
            }
            String s = UUID.randomUUID().toString();
            hkOvertimeInfo.setId(s);
            hkOvertimeInfo.setCreateTime(now);
            hkOvertimeInfo.setFlowTemplateId(hkOvertimeDetailVo.getFlowTemplateId());
            hkOvertimeInfo.setFlowTemplateType(hkOvertimeDetailVo.getFlowType());
            hkOvertimeInfo.setProcessInstanceId(hkOvertimeDetailVo.getProcessInstanceId());
            hkOvertimeInfo.setTotalHours(hkOvertimeDetailVo.getTotalHours());
            hkOvertimeInfo.setCreateBy(hontUserTo.getNickName());
            hkOvertimeInfo.setAssessmentName(hkOvertimeDetailVo.getCause());
            hkOvertimeInfoMapper.insert(hkOvertimeInfo);


            hkOvertimeDetail.setCreateTime(now);
            hkOvertimeDetail.setApprovalUserId(hontUserTo.getId());
            hkOvertimeDetail.setApprovalName(hontUserTo.getNickName());
            hkOvertimeDetail.setProcessInstanceId(hkOvertimeDetailVo.getProcessInstanceId());
            hkOvertimeDetail.setAssessmentStatus("1");
            hkOvertimeDetail.setIsCurrentAssessment("1");
            hkOvertimeDetail.setOverStartTime(overStartTime);
            hkOvertimeDetail.setOverEndTime(overEndTime);
            hkOvertimeDetailMapper.insert(hkOvertimeDetail);

            //如果list=0 并且finish为true 修改统计记录
            List<String> userNames = new ArrayList<>();
            if (hkOvertimeDetailVo.getFlowType() == 3){
                HkOvertimeCollectVo hkOvertimeCollectVo = saveCollect(hkOvertimeInfo, hkOvertimeDetailVo.getHkOvertimeUsers());
                List<String> userName = hkOvertimeCollectVo.getUserName();
                List<String> stringList = saveCollect(hkOvertimeInfo.getTotalHours(), hkOvertimeDetailVo.getHkOvertimeUsers());

                if (stringList.size() > 0){
                    userNames = getUserName(stringList);
                    String join = String.join(",", userNames);
                    if (stringList.size() == hkOvertimeDetailVo.getHkOvertimeUsers().size()){
                        log.info("stringList:{}",stringList);
                        log.info("HkOvertimeUsers:{}",hkOvertimeDetailVo.getHkOvertimeUsers());
                        throw new Exception( join + "今日调休时长已超8小时");
                    }

                    List<HkOvertimeUser> hkOvertimeUsers = new ArrayList<>();
                    for (HkOvertimeUser hkOvertimeUser : hkOvertimeDetailVo.getHkOvertimeUsers()) {
                        if (userNames.contains(hkOvertimeUser.getHontUserId())) {
                            hkOvertimeUsers.add(hkOvertimeUser);
                        }
                    }
                    hkOvertimeDetailVo.getHkOvertimeUsers().removeAll(hkOvertimeUsers);
                }
                if (userName.size() > 0){
                    userNames = getUserName(userName);
                    String join = String.join(",", userNames);
                    if (userName.size() == hkOvertimeDetailVo.getHkOvertimeUsers().size()){
                        throw new Exception( join + "调休时长不足,请重新选择调休人员！");
                    }

                    List<HkOvertimeUser> hkOvertimeUsers = new ArrayList<>();
                    for (HkOvertimeUser hkOvertimeUser : hkOvertimeDetailVo.getHkOvertimeUsers()) {
                        if (userName.contains(hkOvertimeUser.getHontUserId())) {
                            hkOvertimeUsers.add(hkOvertimeUser);
                        }
                    }
                    hkOvertimeDetailVo.getHkOvertimeUsers().removeAll(hkOvertimeUsers);
                }

                if (userName.size() ==0 && finish ){
                    List<HkOvertimeCollect> hkOvertimeCollect = hkOvertimeCollectVo.getHkOvertimeCollect();
                    if (hkOvertimeCollect.size() > 0){
                        hkOvertimeCollect.forEach(hCo -> {
                            hkOvertimeCollectMapper.updateById(hCo);
                        });
                    }

                }
            }
            List<String> strings = iHkOvertimeUserService.addHkOvertimeUsers(hkOvertimeDetailVo.getHkOvertimeUsers(), hkOvertimeInfo.getId(), now);
            if (finish) {
                //如果本月加班汇总为空insert
                //如果不为空update
                if (hkOvertimeDetailVo.getFlowType() == 2){
                    String yearMonthNum = DateUtils.getYearMonthNum();
                    for (int i = 0; i < strings.size(); i++) {
                        QueryWrapper<HkOvertimeCollect> queryWrapper = Wrappers.query();
                        queryWrapper.lambda().eq(HkOvertimeCollect::getDateMoth, yearMonthNum)
                                .eq(HkOvertimeCollect::getHontUserId, strings.get(i));
                        HkOvertimeCollect overtimeCollect = hkOvertimeCollectMapper.selectOne(queryWrapper);
                        HkOvertimeCollect hkOvertimeCollect = saveOvertimeCollect(hkOvertimeDetailVo.getTotalHours(),overtimeCollect, strings.get(i));
                        if (overtimeCollect != null){
                            hkOvertimeCollectMapper.updateById(hkOvertimeCollect);
                        }else {
                            hkOvertimeCollectMapper.insert(hkOvertimeCollect);
                        }
                    }
                }

                strings.forEach(s1 -> {
                    sendMessage(s1);
                });
            }

            //删除key 防止用户重复提交
            redisTemplate.delete(HkOverTimeConstant.SUBMISSION_KEY + hkOvertimeDetailVo.getSubmissionKey());
            return userNames;
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception(e.getMessage());
        } finally {
            lock.unlock();
        }
    }
    public List<String> getUserName(List<String> users) {
        List<String> userNames = new ArrayList<>();
        HontUser hontUser = new HontUser();
        users.forEach(user->{
            hontUser.setId(user);
            HontUser hontUserById = hontUserMapper.getHontUserById(hontUser);
            userNames.add(hontUserById.getNickName());
        });
        return userNames;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Map<String, Object> approvalWithOvertime(SubmitPerformanceDTo submitPerformanceDTo) throws Exception {
        HontUserTo hontUserTo = feignInterface.remoteUserInfo();
        LocalDateTime now = LocalDateTime.now();
        long start = System.currentTimeMillis();
        String assessmentStatus = "";
        if (submitPerformanceDTo.getIsAgree() == 1){
            assessmentStatus = "审核通过";
        }else {
            assessmentStatus = "审核拒绝";
        }


        Result<Object> approval1 = iFlowTaskInstanceService.approval(submitPerformanceDTo.getProcessInstanceId(),assessmentStatus);
        boolean approval = false;
        if (approval1.getCode() == 500) {
            throw new Exception("您没有权限审批此节点");
        } else if (approval1.getCode() == 201){
            throw new Exception("该节点已被其他人审批");
        }else {
            approval = (boolean) approval1.getResult();
        }
        long finish = System.currentTimeMillis();
        long timeElapsed = finish - start;
        log.info("接口调用耗时：{}", timeElapsed);
        /*
         * 修改performanceInfo
         * */
        QueryWrapper<HkOvertimeInfo> query = Wrappers.query();
        query.lambda().eq(HkOvertimeInfo::getProcessInstanceId,submitPerformanceDTo.getProcessInstanceId());
        HkOvertimeInfo hkOvertimeInfo = hkOvertimeInfoMapper.selectOne(query);

        QueryWrapper<HkOvertimeDetail> detailQueryWrapper = Wrappers.query();
        detailQueryWrapper.eq("process_instance_id", submitPerformanceDTo.getProcessInstanceId());
        List<HkOvertimeDetail> hkOvertimeDetails = hkOvertimeDetailMapper.selectList(detailQueryWrapper);
        HkOvertimeDetail hkOvertimeDetailIndexOne = hkOvertimeDetails.get(0);

        QueryWrapper<HkOvertimeUser> queryHistory = Wrappers.query();
        queryHistory.eq("hk_overtime_id", hkOvertimeInfo.getId());
        List<HkOvertimeUser> hkOvertimeUsers = hkOvertimeUserMapper.selectList(queryHistory);

        List<String> strings = hkOvertimeUsers.stream().map(HkOvertimeUser::getHontUserId).collect(Collectors.toList());
        if (submitPerformanceDTo.getIsAgree() == 1 && approval){
            hkOvertimeInfo.setAssessmentStatus("1");
            //如果本月加班汇总为空insert
            //如果不为空update
            if (hkOvertimeInfo.getFlowTemplateType() == 2){
                String yearMonthNum = DateUtils.getYearMonthNum();
                for (int i = 0; i < strings.size(); i++) {
                    QueryWrapper<HkOvertimeCollect> queryWrapper = Wrappers.query();
                    queryWrapper.lambda().eq(HkOvertimeCollect::getDateMoth, yearMonthNum)
                            .eq(HkOvertimeCollect::getHontUserId, strings.get(i));
                    HkOvertimeCollect overtimeCollect = hkOvertimeCollectMapper.selectOne(queryWrapper);
                    HkOvertimeCollect hkOvertimeCollect = saveOvertimeCollect(hkOvertimeInfo.getTotalHours(),overtimeCollect, strings.get(i));
                    if (overtimeCollect != null){
                        hkOvertimeCollectMapper.updateById(hkOvertimeCollect);
                    }else {
                        hkOvertimeCollectMapper.insert(hkOvertimeCollect);
                    }
                }
            }

            if (hkOvertimeInfo.getFlowTemplateType() == 3){
                HkOvertimeCollectVo hkOvertimeCollectVo = saveCollect(hkOvertimeInfo, hkOvertimeUsers);
                List<String> userName = hkOvertimeCollectVo.getUserName();

                if (userName.size() > 0){
                    HontUser hontUser = new HontUser();
                    List<String> userNames = new ArrayList<>();
                    userName.forEach(user->{
                        hontUser.setId(user);
                        HontUser hontUserById = hontUserMapper.getHontUserById(hontUser);
                        userNames.add(hontUserById.getNickName());
                    });
                    String join = String.join(",", userNames);
                    throw new Exception( join + "  以上人员调休时长不足,请通知提交人员！");
                }

                if (userName.size() ==0){
                    List<HkOvertimeCollect> hkOvertimeCollect = hkOvertimeCollectVo.getHkOvertimeCollect();
                    if (hkOvertimeCollect.size() > 0){
                        hkOvertimeCollect.forEach(hCo -> {
                            hkOvertimeCollectMapper.updateById(hCo);
                        });
                    }
                }
            }


            //修改统计记录
        }else if (submitPerformanceDTo.getIsAgree() == 2){
            hkOvertimeInfo.setAssessmentStatus("2");
            hkOvertimeInfo.setEndTime(LocalDateTime.now());
        }else {
            hkOvertimeInfo.setAssessmentStatus("0");
        }
        if (approval) {
            hkOvertimeInfo.setEndTime(LocalDateTime.now());
        }



        HkOvertimeDetail hkOvertimeDetail = new HkOvertimeDetail();
        hkOvertimeDetail.setProcessInstanceId(submitPerformanceDTo.getProcessInstanceId());
        hkOvertimeDetail.setIsCurrentAssessment("2");
        hkOvertimeDetailMapper.updateOvertimeDetailByProcessInstanceId(hkOvertimeDetail);


        HkOvertimeDetail hkOvertimeDetailNew = new HkOvertimeDetail();

        hkOvertimeDetailNew.setCreateTime(now);
        hkOvertimeDetailNew.setApprovalUserId(hontUserTo.getId());
        hkOvertimeDetailNew.setApprovalName(hontUserTo.getNickName());
        hkOvertimeDetailNew.setProcessInstanceId(submitPerformanceDTo.getProcessInstanceId());
        if (submitPerformanceDTo.getIsAgree() == 1){
            hkOvertimeDetailNew.setAssessmentStatus("1");
        }else {
            hkOvertimeDetailNew.setAssessmentStatus("2");
        }
        hkOvertimeDetailNew.setIsCurrentAssessment("1");
        hkOvertimeDetailNew.setOverStartTime(hkOvertimeDetailIndexOne.getOverStartTime());
        hkOvertimeDetailNew.setOverEndTime(hkOvertimeDetailIndexOne.getOverEndTime());
        hkOvertimeDetailNew.setFlowType(hkOvertimeInfo.getFlowTemplateType());
        hkOvertimeDetailNew.setCause(submitPerformanceDTo.getCause());
        hkOvertimeDetailNew.setTotalHours(hkOvertimeDetailIndexOne.getTotalHours());
        hkOvertimeDetailMapper.insert(hkOvertimeDetailNew);


        hkOvertimeInfoMapper.update(hkOvertimeInfo,query);

        if (submitPerformanceDTo.getIsAgree() == 2){
            FlowInstanceinfo flowInstanceinfo = flowInstanceinfoMapper.selectById(submitPerformanceDTo.getProcessInstanceId());
            flowInstanceinfo.setFlowEndTime(LocalDateTime.now());
            flowInstanceinfo.setFlowStatus(2);
            flowInstanceinfoMapper.updateById(flowInstanceinfo);
        }
        /*
         * 业务执行成功后用来判断是否需要发送消息
         * */

        if (approval) {
            hkOvertimeUsers.forEach(t-> {
                sendMessage(t.getHontUserId());
            });
        }
        /*
         * 查找下一个待办
         * */
        Map<String, Object> map = new HashMap<String, Object>();
        List<FlowInstanceinfo> copy = flowInstanceinfoMapper.getBackLog(hontUserTo.getId(),"2");
        if (copy.size() > 0) {
            map.put("processInstanceId", copy.get(0).getId());
            map.put("taskId", copy.get(0).getId());
        } else {
            return null;
        }
        return map;
    }
    public HkOvertimeCollect saveOvertimeCollect(Float totalHours,HkOvertimeCollect overtimeCollect,String userId){
        String yearMonthNum = DateUtils.getYearMonthNum();
        HkOvertimeCollect hkOvertimeCollect = new HkOvertimeCollect();
        HontUser hontUser = hontUserMapper.selectById(userId);

        //本月
        if (overtimeCollect != null){
            overtimeCollect.setOvertimeTotalHours(totalHours + overtimeCollect.getOvertimeTotalHours());
            overtimeCollect.setCurrentmonthSurplusHours(totalHours + overtimeCollect.getCurrentmonthSurplusHours());
            overtimeCollect.setUpdateTime(LocalDateTime.now());
            return overtimeCollect;
        }else {
            hkOvertimeCollect.setHontUserId(userId);
            hkOvertimeCollect.setCreateTime(LocalDateTime.now());
            hkOvertimeCollect.setOvertimeTotalHours(totalHours);
            hkOvertimeCollect.setDaysoffTotalHours(0.0f);
            hkOvertimeCollect.setCurrentmonthSurplusHours(totalHours);
            hkOvertimeCollect.setDateMoth(yearMonthNum);
            hkOvertimeCollect.setDepartmentId(hontUser.getDepartmentId());
            return hkOvertimeCollect;
        }
    }



    public HkOvertimeCollectVo saveCollect(HkOvertimeInfo hkOvertimeInfo, List<HkOvertimeUser> hkOvertimeUsers){
        Float totalHours = getTransitionSix(hkOvertimeInfo.getTotalHours());
        List<String> collect = hkOvertimeUsers.stream().map(HkOvertimeUser::getHontUserId).collect(Collectors.toList());
        HkOvertimeCollectVo hkOvertimeCollectVo = new HkOvertimeCollectVo();
        String yearMonthNum = DateUtils.getYearMonthNum();
        String lastYearMonthNum = DateUtils.getLastYearMonthNum();
        List<String> userNames = new ArrayList<>();
        List<HkOvertimeCollect> hkOvertimeCollects = new ArrayList<>();
        for (int i = 0; i < collect.size(); i++) {
            //本月
            QueryWrapper<HkOvertimeCollect> queryWrapper = Wrappers.query();
            queryWrapper.lambda().eq(HkOvertimeCollect::getDateMoth,yearMonthNum)
                    .eq(HkOvertimeCollect::getHontUserId,collect.get(i));
            HkOvertimeCollect overtimeCollect = hkOvertimeCollectMapper.selectOne(queryWrapper);

            //上月
            QueryWrapper<HkOvertimeCollect> collectQueryWrapper = Wrappers.query();
            collectQueryWrapper.lambda().eq(HkOvertimeCollect::getDateMoth,lastYearMonthNum)
                    .eq(HkOvertimeCollect::getHontUserId,collect.get(i));
            HkOvertimeCollect selectOne = hkOvertimeCollectMapper.selectOne(collectQueryWrapper);

            if (selectOne != null ) {
                if (selectOne.getCurrentmonthSurplusHours() >= totalHours) {
                    //上月
                    selectOne.setCurrentmonthSurplusHours(selectOne.getCurrentmonthSurplusHours() - totalHours);
                    if (overtimeCollect == null){
                        HkOvertimeCollect thisMonthCollect = new HkOvertimeCollect();
                        thisMonthCollect.setHontUserId(selectOne.getHontUserId());
                        thisMonthCollect.setCreateTime(LocalDateTime.now());
                        thisMonthCollect.setOvertimeTotalHours(0.0f);
                        thisMonthCollect.setDaysoffTotalHours(totalHours);
                        thisMonthCollect.setCurrentmonthSurplusHours(0.0f);
                        thisMonthCollect.setDateMoth(yearMonthNum);
                        thisMonthCollect.setDepartmentId(selectOne.getDepartmentId());
                        hkOvertimeCollectMapper.insert(thisMonthCollect);
                    }else {
                        overtimeCollect.setDaysoffTotalHours(overtimeCollect.getDaysoffTotalHours() + totalHours);
                    }
                    hkOvertimeCollects.add(selectOne);
                    hkOvertimeCollects.add(overtimeCollect);
                } else {
                    if (overtimeCollect != null) {
                        if ((selectOne.getCurrentmonthSurplusHours() + overtimeCollect.getCurrentmonthSurplusHours()) >= totalHours) {
                            //调休减上月剩余时长
                            float v = totalHours - selectOne.getCurrentmonthSurplusHours();
                            //本月剩余减V
                            float t = overtimeCollect.getCurrentmonthSurplusHours() - v;
                            //本月
                            overtimeCollect.setCurrentmonthSurplusHours(t);
                            overtimeCollect.setDaysoffTotalHours(totalHours);
                            //上月
                            selectOne.setCurrentmonthSurplusHours(0.0f);
                            hkOvertimeCollects.add(overtimeCollect);
                            hkOvertimeCollects.add(selectOne);
                        } else {
                            userNames.add(collect.get(i));
                        }
                    }else {
                        userNames.add(collect.get(i));
                    }
                }
            } else {
                if (overtimeCollect != null) {
                    if (overtimeCollect.getCurrentmonthSurplusHours() >= totalHours){
                        float v = overtimeCollect.getCurrentmonthSurplusHours() - totalHours;
                        overtimeCollect.setCurrentmonthSurplusHours(v);
                        overtimeCollect.setDaysoffTotalHours(totalHours);
                        hkOvertimeCollects.add(overtimeCollect);
                    }else {
                        userNames.add(collect.get(i));
                    }
                }else {
                    userNames.add(collect.get(i));
                }
            }

        }
        if (hkOvertimeCollects.size() > 0){
            hkOvertimeCollectVo.setHkOvertimeCollect(hkOvertimeCollects);

        }else {
            hkOvertimeCollectVo.setHkOvertimeCollect(new ArrayList<>());

        }
        if (userNames.size() > 0){
            hkOvertimeCollectVo.setUserName(userNames);
        }else {
            hkOvertimeCollectVo.setUserName(new ArrayList<>());
        }
        return hkOvertimeCollectVo;

    }
    //校验当天是否超8小时
    public List<String> saveCollect(Float totalHours, List<HkOvertimeUser> hkOvertimeUsers){
        List<String> collect = hkOvertimeUsers.stream().map(HkOvertimeUser::getHontUserId).collect(Collectors.toList());
        LocalDate now = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String format = now.format(formatter);
        String startOfTime = DateUtils.startOfTime(format);
        String endOfTime = DateUtils.endOfTime(format);
        List<HkOvertimeByPageVo> hkOvertimeByPageVoList = new ArrayList<>();
        collect.forEach(c -> {
            HkOvertimeByPageVo hkOvertimeByPageVo = new HkOvertimeByPageVo();
            hkOvertimeByPageVo.setStartTime(startOfTime);
            hkOvertimeByPageVo.setEndTime(endOfTime);
            hkOvertimeByPageVo.setFlowType("3");
            hkOvertimeByPageVo.setUserId(c);
            hkOvertimeByPageVoList.add(hkOvertimeByPageVo);
        });
        List<String> userIds = new ArrayList<>();
        float e = 8.0f;
        for (int i = 0; i < hkOvertimeByPageVoList.size(); i++) {
            String hkOvertimeInfoByTotalHours = hkOvertimeInfoMapper.getHkOvertimeInfoByTotalHours(hkOvertimeByPageVoList.get(i));
            float aFloat = 0.0f;

            if (StringUtils.isNotBlank(hkOvertimeInfoByTotalHours)){
                aFloat = Float.valueOf(hkOvertimeInfoByTotalHours);
            }
            log.info("totalHours：{}", totalHours);
            log.info("总时长：{}", totalHours + aFloat);
            if ((totalHours + aFloat) > e){
                userIds.add(hkOvertimeByPageVoList.get(i).getUserId());
            }
        }
        return userIds;

    }


    public void sendMessage(String hontUserId) {
        /*
         * 远程调用消息通知
         * */
        List<String> openIdByUserIn = hontUserMapper.getOpenIdByUserIn(hontUserId);
        if (openIdByUserIn.size() > 0) {
            String[] array = new String[openIdByUserIn.size()];
            for (int i = 0; i < openIdByUserIn.size(); i++) {
                array[i] = openIdByUserIn.get(i);
            }
            feignInterface.end(array);
        }
    }

    /**
     * 功能描述:
     * 待办列表
     *
     * @return: java.util.List<com.hkts.naturalgas.performance.performanceVo.PerformanceInfoNameAndUserNickVo>
     * @Author: hml
     * @Date: 22/9/2022 下午3:13
     * @Description //TODO
     */
    @Override
    public Result<List<HkOvertimeInfoNameAndUserNickVo>> getHkOvertimeInfoAndUserNickNameByProIds() {
        HontUserTo hontUserTo = feignInterface.remoteUserInfo();
        List<String> dealtWith = iHkOvertimeInfoService.getDealtWith(hontUserTo.getId());

        log.info("待办列表：{}", dealtWith);
        if (dealtWith.size() == 0) {
            Result<List<HkOvertimeInfoNameAndUserNickVo>> data = ResultUtil.data(null);
            data.setMessage(0 + "");
            return data;
        }
        List<HkOvertimeInfoNameAndUserNickVo> hkOvertimeInfoAndUserNickNameByProIds = hkOvertimeDetailMapper.getHkOvertimeInfoAndUserNickNameByProIds(dealtWith);
        return ResultUtil.data(hkOvertimeInfoAndUserNickNameByProIds);
    }

    @Override
    public HkassessmentOvertimeAndRecordVo getHkOvertimeDetial(String processInstanceId) {

        HkOvertimeInfoNameAndUserNickVo hkOvertimeInfoByProcessId = hkOvertimeDetailMapper.getHkOvertimeInfoByProcessId(processInstanceId);
        QueryWrapper<HkOvertimeInfo> overtimeInfoQueryWrapper = Wrappers.query();
        overtimeInfoQueryWrapper.lambda().eq(HkOvertimeInfo::getProcessInstanceId,processInstanceId);
        HkOvertimeInfo hkOvertimeInfo = hkOvertimeInfoMapper.selectOne(overtimeInfoQueryWrapper);
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        List<HkAssessmentRecordVo> records=new ArrayList<HkAssessmentRecordVo>();
        FlowInstanceinfo flowInstanceinfo = flowInstanceinfoMapper.selectById(processInstanceId);
        QueryWrapper<FlowHistory> query = Wrappers.query();
        query.lambda().eq(FlowHistory::getFlowInstanceId,processInstanceId);
        List<FlowHistory> flowHistories = flowHistoryMapper.selectList(query);
        if (flowInstanceinfo != null){
            HkAssessmentRecordVo record=new HkAssessmentRecordVo();
            record.setTime(flowInstanceinfo.getFlowCreateTime().format(fmt));
            record.setNickName(flowInstanceinfo.getFlowHandler());
            record.setAssessmentStatus("提交申请发起人");
            records.add(record);
        }
        if (flowHistories.size() > 0){
            for (int i = 0; i < flowHistories.size(); i++) {
                HkAssessmentRecordVo record=new HkAssessmentRecordVo();
                record.setTime(flowHistories.get(i).getTaskCreateTime().format(fmt));

                if (flowHistories.get(i).getTaskEndTime() == null){
                    record.setAssessmentStatus("0");
                    FlowTaskInstance flowTaskInstanceByFlowInstance = iFlowTaskInstanceService.getFlowTaskInstanceByFlowInstance(flowHistories.get(i).getFlowInstanceId());
                    List<String> approvalUsers = flowTaskHandlerMapper.getApprovalUsers(flowTaskInstanceByFlowInstance.getId());
                    if (approvalUsers.size() > 0){
                        String join = Joiner.on(",").join(approvalUsers);
                        record.setNickName(join);
                    }
                    Map<String, Object> dateTimePoor = DateUtils.getDateTimePoor(LocalDateTime.now(), flowHistories.get(i).getTaskCreateTime());
                    record.setElapsedTime(dateTimePoor.get("elapsedTime").toString());
                    record.setElapsedTimeStatus(dateTimePoor.get("elapsedTimeStatus").toString());
                }else {
                    record.setAssessmentStatus(flowHistories.get(i).getAssessmentStatus());
                    record.setTime(flowHistories.get(i).getTaskEndTime().format(fmt));
                    Map<String, Object> dateTimePoor = DateUtils.getDateTimePoor(flowHistories.get(i).getTaskEndTime(), flowHistories.get(i).getTaskCreateTime());
                    record.setElapsedTime(dateTimePoor.get("elapsedTime").toString());
                    record.setElapsedTimeStatus(dateTimePoor.get("elapsedTimeStatus").toString());
                    HontUser hontUser = hontUserMapper.selectById(flowHistories.get(i).getTaskHandler());
                    record.setNickName( hontUser.getNickName());

                }

                records.add(record);
            }
        }

            Iterator<HkAssessmentRecordVo> iterator = records.iterator();
            while (iterator.hasNext()){
                HkAssessmentRecordVo next = iterator.next();
                if(next.getAssessmentStatus().equals("0")){
                    iterator.remove();
                }
            }

        HkassessmentOvertimeAndRecordVo vo=new HkassessmentOvertimeAndRecordVo();
        vo.setHkAssessmentRecordVos(records);
        vo.setHkOvertimeDetails(hkOvertimeInfoByProcessId);
        return vo;
    }
}
